/*
 * Copyright 2011 yura.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.opu.db_vdumper.ui.component.tree;

import java.awt.BorderLayout;
import java.awt.Color;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.opu.db_vdumper.ui.component.area.model.CanvesModel;
import org.opu.db_vdumper.ui.component.tabel.models.ColumnModel;
import org.opu.db_vdumper.ui.component.tabel.models.ModelView;
import org.opu.db_vdumper.ui.component.tabel.models.SchemaModel;
import org.opu.db_vdumper.ui.component.tabel.models.TableModel;
import org.opu.db_vdumper.util.Logger;

/**
 *
 * @author yura
 */
public class TreePanel extends JPanel implements ModelView<CanvesModel>{
    public static final int STEP = 12;
    private CanvesModel viewModel;
    private Map<String, SchemaModel> schemNames = new HashMap<String, SchemaModel>();

    public TreePanel(CanvesModel viewModel) {
        super(new BorderLayout(4, 4));
        setBackground(Color.WHITE);
        setViewModel(viewModel);
    }

    @Override
    public CanvesModel getViewModel() {
        return viewModel;
    }

    public void setViewModel(CanvesModel canvesModel){
        this.viewModel = canvesModel;

        if (this.viewModel != null){
            this.viewModel.addViews(this);
        }

        reset();
    }

    @Override
    public void reset() {
        initComponent();

        revalidate();
        repaint();
    }

    private void initComponent() {
        Logger.getInstance().info(this, "init components");
        removeAll();
        Box box = Box.createVerticalBox();
        schemNames.clear();

        if (viewModel == null){
            return;
        }

        Map<SchemaModel, TreeComponent> schemMap =
                new HashMap<SchemaModel, TreeComponent>();
        List<TableModel> tables = viewModel.getTables();

        TreeComponent root = new TreeComponent(viewModel, viewModel.getDatabaseModel(), 1);
        addToBox(box, root);

        for (TableModel tblMdl : tables) {
            String schemaName = tblMdl.getSchema();
            SchemaModel schemaModel = schemNames.get(schemaName);

            if (schemaModel == null){
                schemNames.put(schemaName, schemaModel = new SchemaModel(schemaName));
            }

            TreeComponent schemComp = schemMap.get(schemaModel);

            if (schemComp == null){
                schemMap.put(schemaModel, schemComp = new TreeComponent(
                        viewModel, schemaModel, STEP));
                root.addChildren(schemComp);
            }
            
            TreeComponent tblComp = new TreeComponent(viewModel, tblMdl, STEP * 2);
            schemComp.addChildren(tblComp);
            schemaModel.add(tblMdl);

            for (ColumnModel clMdl : tblMdl.getColumns()) {
                tblComp.addChildren(new TreeComponent(viewModel, clMdl, STEP * 3));
            }
            tblComp.setHidedChildren(false);
        }

        for (JComponent schm : root.getChildrens()) {
            TreeComponent stbl = (TreeComponent) schm;
            addToBox(box, stbl);

            for (JComponent tbl : stbl.getChildrens()) {
                TreeComponent ttbl = (TreeComponent) tbl;
                addToBox(box, ttbl);

                for (JComponent clmn : ttbl.getChildrens()) {
                    TreeComponent ctbl = (TreeComponent) clmn;
                    addToBox(box, ctbl);
                }
            }
        }

        box.add(Box.createVerticalGlue());
        box.setBackground(Color.WHITE);
        add(box, BorderLayout.NORTH);
    }

    private void addToBox(Box box, TreeComponent root) {
        box.add(root);
    }
}
